package cn.edu.nuc.article.util;
import java.io.*;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;

//import cn.hutool.core.io.IoUtil;
import org.apache.commons.io.IOUtils;
import org.bouncycastle.jcajce.io.CipherInputStream;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;

public class SM4Tools {

    private static String key = "05d986b1141227cb20d46d0b5687c4f5";
    private static byte[] keyData = ByteUtils.fromHexString(key);

    static {
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            //No such provider: BC
            Security.addProvider(new BouncyCastleProvider());
        }
    }

    //生成 Cipher
    public static Cipher generateCipher(int mode, byte[] keyData) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException {
        Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS5Padding", BouncyCastleProvider.PROVIDER_NAME);
        Key sm4Key = new SecretKeySpec(keyData, "SM4");
        cipher.init(mode, sm4Key);
        return cipher;
    }


    //加密文件
    public static CipherInputStream encryptFile(InputStream in) {
        //加密文件
        try {
            Cipher cipher = generateCipher(Cipher.ENCRYPT_MODE, keyData);
            CipherInputStream cipherInputStream = new CipherInputStream(in, cipher);
            //        FileUtil.writeFromStream(cipherInputStream, targetPath);
            return cipherInputStream;

        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 解密文件
     *
     * @return
     */
    public static CipherInputStream decryptFile(InputStream cipherin) {
        ByteArrayInputStream byteArrayInputStream = null;
        //OutputStream out = null;
        CipherOutputStream cipherOutputStream = null;
        try {
            //byte[] bytes = IoUtil.readBytes(cipherin);
            ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
            byte[] bytes = new byte[100];
            int rc = 0;
            while ((rc = cipherin.read(bytes, 0, 100)) > 0) {
                swapStream.write(bytes, 0, rc);
            }
            byte[] in2b = swapStream.toByteArray();
            //byteArrayInputStream = IoUtil.toStream(in2b);
            byteArrayInputStream = new ByteArrayInputStream(in2b);

            Cipher cipher = generateCipher(Cipher.DECRYPT_MODE,keyData);

         //   out = new FileOutputStream(targetPath);
            //cipherOutputStream = new CipherOutputStream(b, cipher);
            CipherInputStream cipherInputStream = new CipherInputStream(byteArrayInputStream,cipher);
            //IoUtil.copy(byteArrayInputStream, cipherOutputStream);
            return cipherInputStream;
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return null;
    }
}
